package com.hns.can.common.formula;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.hns.can.base.entity.SysUserEntity;
import com.hns.can.common.constants.GlobalConst;
import com.hns.can.common.entity.BaseEntity;
import com.hns.can.common.service.CacheTaskManager;
import com.hns.can.common.vo.SysCacheVo;
import com.hns.frame.util.EntityUtil;
import com.hns.frame.util.ReflectUtil;
import com.hns.tool.pub.ContextHolderUtils;
import com.hns.tool.pub.HashKeyAdapter;
import com.hns.tool.pub.Hashlize;
import com.hns.tool.pub.PubUtil;

/**
 * 
 * @description：填充代码表中代码字段为代码描述
 * @author：wucx
 * Create Date: 2014年7月31日 下午3:43:24
 */
@Component
public class FillCodeDscValue  {
    private static final Logger logger = LoggerFactory.getLogger(FillCodeDscValue.class);

    @Autowired
    private CacheTaskManager cacheTaskManager;
    
    /**
     * @author：wucx
     * @description：将参数代码填充为参数描述
     * @param resoureDateList 填充列表对象
     * @param fillFieldType：    key 填充列表中填充属性名，value 代码表中的代码类型值
     *                      如：
     *                          carType(车辆类型)->CAR00000;
     *                          flOilType(燃油类型)->FUT00000;
     * @date：2014年8月1日 上午11:36:06
     */
    @SuppressWarnings("unchecked")
    public void fillCodeDscValue(List<BaseEntity> resoureDateList, Map<String,String> fillFieldType){
        HttpServletRequest request = ContextHolderUtils.getRequest();
        SysUserEntity user = getSysUserEntity(request);
        if(PubUtil.isEmpty(resoureDateList) || PubUtil.isEmpty(fillFieldType))
            return;
        
        //从缓存取参数表Map
        Map<String, List<SysCacheVo>> codeMap =  new HashMap<String, List<SysCacheVo>>();
        
        codeMap.putAll((Map<? extends String, ? extends List<SysCacheVo>>) cacheTaskManager.loadCache(GlobalConst.CACHE_KEY_SYS_CODE, user.getCorpId()));
        //遍历需要填充代码描述的数据列表
        Set<String> keyList = fillFieldType.keySet();
        for (String key : keyList) {
            String codeType = fillFieldType.get(key);
            Map<String,SysCacheVo> codeDscMap = Hashlize.hashlizeMap(codeMap.get(codeType), 
                    new HashKeyAdapter(new String[]{"key"}));
            if(PubUtil.isEmpty(codeDscMap)){
                continue;
            }
            for (BaseEntity baseEntity : resoureDateList) {
                //取参数对象
                String codeValue = (String)EntityUtil.getFieldValueByFieldName(baseEntity, key);
                if(PubUtil.isEmpty(codeValue))
                    continue;
                SysCacheVo codeDscVo = codeDscMap.get(codeValue);
                if(PubUtil.isEmpty(codeDscVo)){
                    continue;
                }
                try {
                    BeanUtils.copyProperty(baseEntity, key, codeDscVo.getValue());
                } catch (IllegalAccessException | InvocationTargetException e) {
                    logger.error(e.getMessage(), e);
                } 
            }
        }
    }
    /**
     * 填充对应缓存里面的值
     * @param resoureDateList   数据源
     * @param cacheArray    缓存数组(顺序不固定)
     * @param voArray   填充值的对应关系(顺序不固定)
     * @throws Exception
     * @author:Fisher
     * @email:zhuangcaijin@126.com
     */
    @SuppressWarnings("unchecked")
    public void fillInfoValue(List resoureDateList,String[] cacheArray, FillParamsVo... voArray) throws Exception{
        
        HttpServletRequest request = ContextHolderUtils.getRequest();
        SysUserEntity user = getSysUserEntity(request);
        if(PubUtil.isEmpty(resoureDateList) || PubUtil.isEmpty(cacheArray) || PubUtil.isEmpty(voArray)){
            return;
        }
        //获取需要用到的缓存信息
        List<SysCacheVo> list = new ArrayList<SysCacheVo>();
        for(String cacheType : cacheArray){
        	Object obj = cacheTaskManager.loadCache(cacheType, user.getCorpId());
        	if(PubUtil.isNotEmpty(obj)){
        		list.addAll((List<SysCacheVo>)obj);
        	}
//        	else{//如果获取不到指定缓存，则清除，并重新缓存
//        		logger.error("!!!!!!!!!!!!!!!!!!!!!!!!!!未能读取企业id为"+user.getCorpId()+"的缓存，缓存类型："+cacheType+"!!!!!!!!!!!!!!!!!!!!!!!!!!!");
//        		cacheTaskManager.cleanCache(cacheType, user.getCorpId());
//        		list.addAll((List<SysCacheVo>)cacheTaskManager.loadCache(cacheType, user.getCorpId()));
//        	}
        }
        //将缓存信息转化为key - value形式
        Map<String,SysCacheVo> codeDscMap = Hashlize.hashlizeMap(list, 
            new HashKeyAdapter(new String[]{"key"}));
        
        //遍历列表
        for (Object baseEntity : resoureDateList) {
            // 遍历需要填充字段
            for (FillParamsVo vo : voArray) {
                String id = vo.getId();//主键id的名称
                String codeValue = (String)ReflectUtil.getFieldValue(baseEntity, id);//主键的值
                if(PubUtil.isEmpty(codeValue)){
                    continue;
                }
                SysCacheVo codeDscVo = codeDscMap.get(codeValue);//获取主键相关的缓存实体
                if(PubUtil.isEmpty(codeDscVo)){
                    continue;
                }
                Map<String, String> map = vo.getMap();
                Set<String> keyList = map.keySet();
                //遍历需要转化的属性值
                for (String key : keyList) {
                    String codeDsc = map.get(key);
                    BeanUtils.copyProperty(baseEntity, key, ReflectUtil.getFieldValue(codeDscVo, codeDsc));
                }
            }
        }
        
    }
    
    /**
     * 获取当前用户
     * @param request
     * @return
     */
    public SysUserEntity getSysUserEntity(HttpServletRequest request){
    	SysUserEntity user = (SysUserEntity)request.getSession().getAttribute("SES_CURRENTUSER");
        if(PubUtil.isEmpty(user)){
        	user = (SysUserEntity) request.getSession().getAttribute("PHONE_CURRENTUSER");
        }
        return user;
    }

}
